package study.activiti.g_exclusiveGateway;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

/**  
 * @Name: ExclusiveGatewayTest
 * @Description: 排他网关测试类,由于存在排他网关，因此在办理任务时需指定流程变量，以决定流程下一步走哪一条连线
 * @Author: 李超
 * @Create Date: 2016-12-14
 */
public class ExclusiveGatewayTest {
	
	//流程引擎
	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine() ;
	
	/**  
	* @Name: delpoymentProcessDefinition_inputStream（方法的名称）
	* @Description: 部署流程定义文件（输入流加载资源文件）（方法的描述）
	* 输入流加载资源文件的三种方式
	* 		1、从classpath跟目录下加载指定名称的文件，不加斜杠
	* 		  InputStream in = this.getClass().getClassLoader().getResourceAsStream("test.bpmn") ;
	* 		2、从当前包下加载指定名称的文件
	* 		  InputStream in = this.getClass().getResourceAsStream("test.bpmn") ;
	* 		3、从classpath跟目录下加载指定名称的文件，加斜杠
	* 		  this.getClass().getResourceAsStream("/test.bpmn") ;
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-11 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	@Test
	public void delpoymentProcessDefinition_inputStream() {
		//流程资源文件输入流
		InputStream inputStreamBpmn = this.getClass().getResourceAsStream("exclusiveGateway.bpmn") ;
		InputStream inputStreamPng = this.getClass().getResourceAsStream("exclusiveGateway.png") ;
		//部署流程定义
		Deployment deployment = processEngine.getRepositoryService()
					 .createDeployment()
					 .name("排他网关")
					 .addInputStream("exclusiveGateway.bpmn", inputStreamBpmn)
					 .addInputStream("exclusiveGateway.png", inputStreamPng)
					 .deploy() ;
		System.out.println("部署id:" + deployment.getId());
		System.out.println("部署名称:" + deployment.getName());
		System.out.println("部署时间:" + deployment.getDeploymentTime());
	}
	
	/**  
	* @Name: startProcessDefinition（方法的名称）
	* @Description: 启动流程定义（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-14 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	@Test
	public void startProcessInstance() {
		//流程定义key
		String processDefinitionKey = "exclusiveGateway" ;
		//根据流程定义的key启动流程实例
		ProcessInstance processInstance = processEngine.getRuntimeService()
					 .startProcessInstanceByKey(processDefinitionKey) ;
		System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
		System.out.println("流程实例id:" + processInstance.getId());
	}
	
	/**  
	* @Name: queryMyPersonalTask（方法的名称）
	* @Description: 查询指定任务办理人的个人任务（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-14 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	@Test
	public void queryMyPersonalTask() {
		//任务办理人
		String assignee = "王小五" ;
		//查询王小五待办理的个人任务
		List<Task> list = processEngine.getTaskService()
					 .createTaskQuery()
					 .taskAssignee(assignee)
					 .orderByTaskCreateTime().asc()
					 .list() ;
		if(list != null && list.size() > 0) {
			for (Task task : list) {
				System.out.println("任务id:" + task.getId());
				System.out.println("任务名称:" + task.getName());
				System.out.println("任务办理人:" + assignee);
				System.out.println("任务创建时间:" + task.getCreateTime());
				System.out.println("流程实例id:" + task.getProcessInstanceId());
				System.out.println("执行对象id:" + task.getExecutionId());
				System.out.println("###################################");
			}
		}
	}
	
	/**  
	* @Name: completeMyPersonalTask（方法的名称）
	* @Description: 办理个人任务，由于存在排他网关，因此在办理任务时需指定流程变量，以决定流程下一步走哪一条连线（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-14 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	@Test
	public void completeMyPersonalTask() {
		//任务id
		String taskId = "117504" ;
		//流程变量
		Map<String, Object> variables = new HashMap<String, Object>() ;
		variables.put("money", 15000) ;
		//根据任务id办理个人任务，同时设置流程变量，指定排他网关下一步走哪一条连线
		processEngine.getTaskService().complete(taskId, variables) ;
		System.out.println("办理成功");
	}
	
	/**  
	* @Name: queryHistoricVariables（方法的名称）
	* @Description: 查询历史流程变量（方法的描述）
	* @Author: 李超（作者）
	* @Version: V1.00 （版本号）
	* @Create Date: 2016-12-14 （创建日期）
	* @Parameters: 无（方法的入参，如果没有，填写为“无”）
	* @Return: 无（返回值，如果没有，填写为“无”）
	*/
	@Test
	public void queryHistoricVariables() {
		//流程变量名称
		String variableName = "money" ;
		//根据流程变量名称查询所有的历史流程变量
		List<HistoricVariableInstance> list = processEngine.getHistoryService()
					 .createHistoricVariableInstanceQuery()
					 .variableName(variableName)
					 .list() ;
		if(list != null && list.size() > 0) {
			for (HistoricVariableInstance hvi : list) {
				System.out.println("流程实例id:" + hvi.getProcessInstanceId());
				System.out.println("流程变量名称:" + hvi.getVariableName());
				System.out.println("流程变量类型:" + hvi.getVariableTypeName());
				System.out.println("流程变量内容:" + hvi.getValue());
				System.out.println("###################################");
			}
		}
	}
	
}
